<?php
namespace service;

use service\asynctask\Helper;
use service\asynctask\TaskConfig;
use think\facade\Log;
use think\Request;
use think\Route;
use think\Service;

class AsyncTaskService extends Service
{
    private static $task = [];

    /**
     * 服务注册引导
     *
     * @param Route $route
     * @param Request $request
     * @return void
     */
    public function boot(Route $route,Request $request)
    {
        $route->post('async/task', AsyncTaskService::class."@taskDeal");
    }

    public static function async($task_name,$param=[])
    {
        $domain = request()->domain();

        self::$task[]=[
            'url'=>$domain.'/async/task',
            'method'=>'POST',
            'data'=>['name'=>$task_name,'param'=>json_encode($param)]
        ];

    }

    public static function send()
    {
        if(empty(self::$task))return true;

        foreach (self::$task as $value) {
            Helper::curl($value['url'],$value['method'],$value['data']);
        }
    }

    public function taskDeal(Request $request)
    {
        $this->quickRespone('success');

        ignore_user_abort(true);
        set_time_limit(0);

        $param = $request->param();

        Log::write('[异步任务]进入异步任务,参数'.json_encode($param));

        if(empty($param['name'])){
            Log::write('[异步任务]缺少必要参数 name');
            return;
        }

        if(empty($param['param'])){
            Log::write('[异步任务]缺少必要参数 param');
            return;
        }

        $task = (new TaskConfig())->task($param['name']);

        if(!$task){
            Log::write('[异步任务]任务 "'.$param['name'].'" 不存在');
            return;
        }

        Log::write('[异步任务]开始任务处理,task:'.json_encode($task));

        try {
            $class = new $task[0]();
            $method = $task[1];
            $class->$method(json_decode($param['param'],true));
            return 'Suceess';
        } catch (\Throwable $th) {
            Log::write('[异步任务]执行错误：'.$th);
            return $th->getMessage();
        }

    }

    /**
     * 查询web服务器类型
     *
     * @return void
     */
    private function queryWebServer()
    {
        $sapi = PHP_SAPI;
        $val = null;
        switch ($sapi) {
            case 'fpm-fcgi':
                $val = 'nginx';
                break;
            case 'cgi-fcgi':
                $val = 'nginx';
                break;
            case 'apache2handler':
                $val = 'apache';
                break;
            case 'cli':
                $val = 'cli';
                break;
            default:
                $val = $sapi;
                break;
        }
        return $val;
    }
    
    /**
     * 异步任务快速响应，关闭客户端
     *
     * @param string $str
     * @return void
     */
    private function quickRespone($str = 'wait!')
    {
        ini_set('max_execution_time', '0');

        $webServer = $this->queryWebServer();

        if ($webServer == 'nginx') {
            echo $str;
            fastcgi_finish_request();
        } else if ($webServer == 'apache') {
            ob_end_flush();
            ob_start();
            echo $str;
    
            header("Content-Type: text/html;charset=utf-8");
            header("Connection: close");
            header('Content-Length: ' . ob_get_length());
    
            ob_flush();
            flush();
        }
    }
    
}